/**
 *
 */
package jp.seraph.jsade.model;

import jp.seraph.jsade.math.Angle;
import jp.seraph.jsade.math.Point3D;

import org.apache.commons.math.geometry.Vector3D;

/**
 * ModelPartsのデフォルト実装です
 *
 */
public class DefaultModelPart implements ModelPart {
    /**
     * 引数を指定しないコンストラクタです。
     * このコンストラクタを使用した場合、必ずinitメソッドで初期化を行ってください。
     */
    public DefaultModelPart(){

    }

    public DefaultModelPart(String aName, double aMass, Vector3D aTranslation, Joint aParentJoint, Joint... aChildJoints){
        this.init(aName, aMass, aTranslation, aParentJoint, aChildJoints);
    }

    public void init(String aName, double aMass, Vector3D aTranslation, Joint aParentJoint, Joint... aChildJoints){
        mName = aName;
        mMass = aMass;
        mTranslation = aTranslation;
        mParentJoint = aParentJoint;
        mChildJoints = aChildJoints;
    }

    private String mName;
    private Vector3D mTranslation;
    private Joint mParentJoint;
    private Joint[] mChildJoints;
    private double mMass;

    /**
     *
     * @see jp.seraph.jsade.model.ModelPart#getChildJoint(int)
     */
    
    public Joint getChildJoint(int aIndex) {
        if(aIndex < 0 || aIndex <= mChildJoints.length)
            return null;

        return mChildJoints[aIndex];
    }

    /**
     *
     * @see jp.seraph.jsade.model.ModelPart#getChildJoint(java.lang.String)
     */
    
    public Joint getChildJoint(String aName) {
        for(Joint tJoint : mChildJoints){
            if(tJoint.getName().equals(aName)){
                return tJoint;
            }
        }

        return null;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getChildObject(int)
     */
    
    public ModelObject getChildObject(int aIndex) {
        Joint tChild = this.getChildJoint(aIndex);
        if(tChild == null) return null;

        return tChild.getObject();
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getChildObject(java.lang.String)
     */
    
    public ModelObject getChildObject(String aName) {
        Joint tChild = this.getChildJoint(aName);
        if(tChild == null) return null;

        return tChild.getObject();
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getJointCount()
     */
    
    public int getJointCount() {
        return mChildJoints.length;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getParentJoint()
     */
    
    public Joint getParentJoint() {
        return mParentJoint;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getParentObject()
     */
    
    public ModelObject getParentObject() {
        if(this.isRoot())
            return null;
        return this.getParentJoint().getObject();
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#getTranslation()
     */
    
    public Vector3D getTranslation() {
        return mTranslation;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelPart#isRoot()
     */
    
    public boolean isRoot() {
        return mParentJoint == null;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelObject#getAbsoluteCoordinate()
     */
    
    public Point3D getAbsoluteCoordinate() {
        if(this.isRoot())
            return Point3D.origin;

        return this.getCoordinateAsRoot(Point3D.origin);
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelObject#getCentorOfGravity()
     */
    
    public Point3D getCentorOfGravity() {
        return this.getAbsoluteCoordinate();
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelObject#getMass()
     */
    
    public double getMass() {
        return mMass;
    }

    /**
     *
     *
     * @see jp.seraph.jsade.model.ModelObject#getName()
     */
    
    public String getName() {
        return mName;
    }

    /**
     *
     * @see jp.seraph.jsade.model.CoordinateSystem#getAxis()
     */
    
    public Vector3D getAxis() {
        return Vector3D.zero;
    }

    /**
     *
     * @see jp.seraph.jsade.model.CoordinateSystem#getCoordinateAsRoot(jp.seraph.jsade.math.Point3D)
     */
    
    public Point3D getCoordinateAsRoot(Point3D aLocalPoint) {
        if(this.isRoot())
            return aLocalPoint;

        // このオブジェクトの座標系は、ParentJoint座標系を、Translationだけ平行移動させたもの
        return this.getParentJoint().getCoordinateAsRoot(aLocalPoint.add(this.getTranslation()));
    }

    /**
     *
     * @see jp.seraph.jsade.model.CoordinateSystem#getRelativeAngle()
     */
    
    public Angle getRelativeAngle() {
        return Angle.ZERO;
    }

    /**
     *
     * @see jp.seraph.jsade.model.CoordinateSystem#getRelativeAngleAsRad()
     */
    
    public double getRelativeAngleAsRad() {
        return 0;
    }

}
